package com.baitiaojun.web.core.handler;

import com.baitiaojun.common.constants.HttpStatus;
import com.baitiaojun.common.domain.model.result.CommonResult;
import com.baitiaojun.common.enums.impl.ServerExpEnums;
import com.baitiaojun.common.exception.ServerException;
import com.baitiaojun.common.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.security.access.AccessDeniedException;

import javax.servlet.http.HttpServletRequest;

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    /**
     * jsr303验证异常
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public CommonResult handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.error(e.getMessage(), e);
        FieldError fieldError = e.getBindingResult().getFieldError();
        assert fieldError != null; // 断言，避免告警
        return CommonResult.error(HttpStatus.BAD_REQUEST, fieldError.getDefaultMessage());
    }

    /**
     * 权限校验异常
     */
    @ExceptionHandler(AccessDeniedException.class)
    public CommonResult handleAccessDeniedException(AccessDeniedException e, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',权限校验失败'{}'", requestURI, e.getMessage());
        ServerExpEnums expAccessDenied = ServerExpEnums.EXP_ACCESS_DENIED;
        return CommonResult.error(expAccessDenied.getCode(), expAccessDenied.getName());
    }

    /**
     * 请求方式不支持异常
     * @param e
     * @param request
     * @return
     */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public CommonResult handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e,
                                                          HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        ServerExpEnums expMethodNotSupport = ServerExpEnums.EXP_METHOD_NOT_SUPPORT;
        log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod());
        return CommonResult.error(expMethodNotSupport.getCode(), expMethodNotSupport + "'" + request.getMethod() + "'");
    }

    /**
     * 业务异常
     * @param exception
     * @return
     */
    @ExceptionHandler(ServiceException.class)
    public CommonResult serviceException(ServiceException exception, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        String message = exception.getMessage();
        log.warn("请求地址'{}', 异常原因'{}'", requestURI, message);
        return CommonResult.error(exception.getCode(), message);
    }

    /**
     * 系统异常
     * @param exception
     * @return
     */
    @ExceptionHandler(ServerException.class)
    public CommonResult serverException(ServerException exception, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        String message = exception.getMessage();
        log.warn("请求地址'{}', 异常原因'{}'", requestURI, message);
        return CommonResult.error(exception.getCode(), message);
    }

    /**
     * 全局异常
     * @param exception
     * @return
     */
    @ExceptionHandler(Exception.class)
    public CommonResult defaultException(Exception exception, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        String message = exception.getMessage();
        log.error("请求地址'{}',异常原因'{}'", requestURI, message);
        return CommonResult.error(message);
    }
}
